const crypto = require('crypto');
const url = require('url');
const cheerio = require('cheerio');
const rp = require('request-promise');
const Client = require('aliyun-api-gateway').Client;
const client = new Client('24725606', 'b918d557ca663e468ec4f731c1ff6cc1');
const query = require('./utils/mysql');

const href = `http://weixin.sogou.com/weixin?type=1&s_from=input&query=神木&ie=utf8&_sug_=n&_sug_type_=`;
const list = [];

let cookieJar = rp.jar();
/**
 * 获取所有的公众号
 * @param page
 * @param verified
 * @returns {Promise.<void>}
 */
const getAll = async (page = 1, verified) => {
  const uri = `${encodeURI(href)}&page=${page}`;
  const Referer = `http://weixin.sogou.com/antispider/?from=${uri.split('?')[1]}`
  const headers = {
    'X-Requested-With': 'XMLHttpRequest',
    'Cookie': cookieJar.getCookieString(uri)
  };
  if (verified) {
    console.log('[cookie] ', cookieJar.getCookieString(uri));
    headers.Referer = Referer
  }
  const $ = await rp({
    uri,
    headers: headers,
    transform: function (body) {
      return cheerio.load(body);
    },
    jar: cookieJar,
  });

  // 需要输入验证码
  if ($('.p3').text().indexOf('验证码') !== -1) {
    const codeUrl = `http://weixin.sogou.com/antispider/${$('#seccodeImage').attr('src')}`;
    console.log('[verifycode url]: ', codeUrl);
    await verifyCode(uri, codeUrl).catch(ex => {
      console.log(ex);
    });
    console.log('验证成功，重新访问...');
    await getAll(page, true);
  }

  const $lis = $('.news-list2 li');

  for (let i = 0, len = $lis.length; i < len; i++) {
    const obj = {};
    const ImgBox = $($lis[i]).find('.img-box');
    const TxtBox = $($lis[i]).find('.txt-box');
    const Info = $($lis[i]).find('dl').first();
    obj.logo = ImgBox.find('a img').attr('src');
    obj.url = ImgBox.find('a').attr('href');
    obj.name = TxtBox.find('.tit').text().trim();
    obj.num = TxtBox.find('.info label').text().trim();
    obj.info = Info.find('dd').text().trim();
    list.push(obj);
  }

  // 总记录数
  const totalNum = $('.mun').text().replace(/\D/img, '');
  // 总页数
  const totalPage = Math.ceil(+totalNum / 10);
  console.log('[总页码] ', totalPage);
  if (page < totalPage) {
    setTimeout(async () => {
      await getAll(page + 1);
    }, 0);
  } else {
    console.log(list);
    console.log(list.length);
    const values = list.reduce((acc, curr, index, arr) => {
      const { name, num, info, logo, url } = curr;
      return `${acc}("${name}", "${num}", "${info}", "${logo}", "${url}")${index < arr.length - 1 ?
        ',' :
        ''}`;
    }, '');

    console.log('[保存到数据库]');

    // 存入数据库
    const res = await query(`INSERT INTO source (name,num,info,logo,url) VALUES ${values}`);

    if (res instanceof Error || res.affectedRows === 0) {
      console.log('[error]');
      console.log(res);
      process.exit(0);
      return;
    }

    console.log('[保存成功]');
  }
};

/**
 * 使用阿里云解决验证问题
 * @param uri
 * @param imgUrl
 * @returns {Promise.<boolean>}
 */
const verifyCode = async (uri, imgUrl) => {
  const Referer = `http://weixin.sogou.com/antispider/?from=${uri.split('?')[1]}`;
  const verifycodeBase64 = await rp({
    uri: imgUrl,
    encoding: 'base64',
    headers: {
      'Cookie': cookieJar.getCookieString(Referer),
      'Referer': Referer
    },
    jar: cookieJar,
  }).catch(ex => console.log('验证码获取base64失败： ', ex));

  // const verifycode = `data:image/jpeg;base64,${code}`;
  // console.log('[verifycode base64]: ', verifycode);

  // 使用阿里验证码服务获取验证码文本
  const verifyCodeText = await client.post('http://jisuyzmsb.market.alicloudapi.com/captcha/recognize', {
    query: {
      type: 'en6',
    },
    data: {
      pic: verifycodeBase64,
    },
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
    },
  });

  if (Number.parseInt(verifyCodeText.status, 10) === 0) {
    console.log('[识别出的验证码文本：]', verifyCodeText.result.code);
    // 提交验证码
    const goVerify = await rp({
      method: 'POST',
      uri: 'http://weixin.sogou.com/antispider/thank.php',
      form: {
        c: verifyCodeText.result.code,
        r: url.parse(uri).path,
        v: 5,
      },
      headers: {
        'Referer': Referer,
        'Cookie': cookieJar.getCookieString(imgUrl)
      },
      jar: cookieJar,
      json: true,
      transform: function (body) {
        cookieJar.setCookie(
          rp.cookie('seccodeRight=success'),
          uri
        );
        cookieJar.setCookie(
          rp.cookie(`SUV=${1E3 * (new Date).getTime() + Math.round(1E3 * Math.random())}`),
          uri
        );
        cookieJar.setCookie(
          rp.cookie(`SNUID=${body.id}`),
          uri
        );
        return body
      }
    });
    // 验证成功
    if (goVerify.code === 0) {
      console.log('验证成功');
      return true;
    }

    console.log('验证失败，重试');
    await resolveVerifyCode(imgUrl);

  }
};

getAll();
